import java.util.*;
import java.io.*;
import java.security.MessageDigest;
import com.evernote.edam.type.*;
import com.evernote.edam.userstore.*;
import com.evernote.edam.notestore.*;
import com.facebook.thrift.*;
import com.facebook.thrift.protocol.TBinaryProtocol;
import com.facebook.thrift.transport.THttpClient;

public class EDAMDemo {

    public static void main(String args[]) throws Exception {
        String username = "dave";
        String password = "$ecr3T!";
        String consumerKey = "client-key-1";
        String consumerSecret = "0a1b2c3d4e5f";
        String userStoreUrl = "https://sandbox.evernote.com/edam/user";
        String noteStoreUrlBase = "http://sandbox.evernote.com/edam/note/";

        // Set up the UserStore and check that we can talk to the server
        THttpClient userStoreTrans = new THttpClient(userStoreUrl);
        TBinaryProtocol userStoreProt = new TBinaryProtocol(userStoreTrans);
        UserStore.Client userStore =
            new UserStore.Client(userStoreProt, userStoreProt);
        boolean versionOk =
            userStore.checkVersion("Dave's EDAMDemo (Java)",
                 com.evernote.edam.userstore.Constants.EDAM_VERSION_MAJOR,
                 com.evernote.edam.userstore.Constants.EDAM_VERSION_MINOR);
        if (!versionOk) {
            System.err.println("Incomatible EDAM client protocol version");
            return;
        }

        // Authenticate as a user & password
        AuthenticationResult authResult =
            userStore.authenticate(username, password,
            		               consumerKey, consumerSecret);
        User user = authResult.getUser();
        String authToken = authResult.getAuthenticationToken();
        
        // Set up the NoteStore
        System.out.println("Notes for " + user.getUsername() + ":");
        String noteStoreUrl = noteStoreUrlBase + user.getShardId();
        THttpClient noteStoreTrans = new THttpClient(noteStoreUrl);
        TBinaryProtocol noteStoreProt = new TBinaryProtocol(noteStoreTrans);
        NoteStore.Client noteStore =
            new NoteStore.Client(noteStoreProt, noteStoreProt);
        
        // List all of the notes in the account
        List<Notebook> notebooks =
            (List<Notebook>) noteStore.listNotebooks(authToken);
        Notebook defaultNotebook = notebooks.get(0);
        for (Notebook notebook : notebooks) {
            System.out.println("Notebook: " + notebook.getName());
            NoteFilter filter = new NoteFilter();
            filter.setNotebookGuid(notebook.getGuid());
            NoteList noteList = noteStore.findNotes(authToken, filter, 0, 100);
            List<Note> notes = (List<Note>) noteList.getNotes();
            for (Note note : notes) {
                System.out.println(" * " + note.getTitle());
            }
            if (notebook.isDefaultNotebook()) {
                defaultNotebook = notebook;
            }
        }
        
        // Create a note containing a little text, plus the "enlogo.png" image
        Resource resource = new Resource();
        resource.setData(readFileAsData("enlogo.png"));
        resource.setMime("image/png");
        Note note = new Note();
        note.setTitle("Test note from EDAMDemo");
        note.setCreated(System.currentTimeMillis());
        note.setUpdated(System.currentTimeMillis());
        note.setActive(true);
        note.setNotebookGuid(defaultNotebook.getGuid());
        note.addToResources(resource);
        String hashHex = bytesToHex(resource.getData().getBodyHash());
        String content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
            "<!DOCTYPE en-note SYSTEM \"http://xml.evernote.com/pub/enml.dtd\">" +
            "<en-note>Here's the Evernote logo:<br/>" +
            "<en-media type=\"image/png\" hash=\"" + hashHex + "\"/>" +
            "</en-note>";
        note.setContent(content);
        Note createdNote = noteStore.createNote(authToken, note);
        System.out.println("Note created. GUID: " + createdNote.getGuid());
    }


    private static Data readFileAsData(String fileName) throws Exception {
        FileInputStream in = new FileInputStream(fileName);
        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
        byte[] block = new byte[10240];
        int len;
        while ((len = in.read(block)) >= 0) {
            byteOut.write(block, 0, len);
        }
        in.close();
        byte[] body = byteOut.toByteArray();
        Data data = new Data();
        data.setSize(body.length);
        data.setBodyHash(MessageDigest.getInstance("MD5").digest(body));
        data.setBody(body);
        return data;
    }

    public static String bytesToHex(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (byte hashByte : bytes) {
            int intVal = 0xff & hashByte;
            if (intVal < 0x10) {
                sb.append('0');
            }
            sb.append(Integer.toHexString(intVal));
        }
        return sb.toString();
  }

}
